package com.aracky.assess.service.impl;

import com.aracky.assess.mapper.HrKpiUserPerformanceDetailMapper;
import com.aracky.assess.mapper.HrKpiUserPerformanceHeaderMapper;
import com.aracky.assess.model.entity.HrKpiUserAssessorConfig;
import com.aracky.assess.model.entity.HrKpiUserPerformanceDetail;
import com.aracky.assess.model.entity.HrKpiUserPerformanceHeader;
import com.aracky.assess.model.excel.KpiUserHeaderExport;
import com.aracky.assess.model.form.*;
import com.aracky.assess.model.request.HrKpiUserPerformanceHeaderRequest;
import com.aracky.assess.model.vo.HrKpiUserPerformanceHeaderExcelVO;
import com.aracky.assess.model.vo.HrKpiUserPerformanceHeaderVO;
import com.aracky.assess.service.*;
import com.aracky.common.util.ComUtil;
import com.aracky.common.util.ConvertUtil;
import com.aracky.common.util.UserIPUtil;
import com.aracky.common.vo.PageVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

import static com.aracky.assess.constants.ComConstants.KPI.ASSESSOR_COMPLETE_STRINGS;
import static com.aracky.assess.constants.ComConstants.KPI.EMP_COMPLETE_STRINGS;


/**
 * <p>
 * 用户绩效考核 服务实现类
 * </p>
 *
 * @author zzp
 * @since 2022-08-01 09:43:18
 */
@Service
public class HrKpiUserPerformanceHeaderServiceImpl extends ServiceImpl<HrKpiUserPerformanceHeaderMapper, HrKpiUserPerformanceHeader> implements HrKpiUserPerformanceHeaderService {
    @Resource
    private HrKpiUserAssessorConfigService hrKpiUserAssessorConfigService;

    @Resource
    private HrKpiUserPerformanceHeaderService hrKpiUserPerformanceHeaderService;

    @Autowired
    private HrKpiUserPerformanceDetailService hrKpiUserPerformanceDetailService;

    @Resource
    private HrKpiUserPerformanceDetailMapper hrKpiUserPerformanceDetailMapper;

    @Resource
    private HrKpiPostPerformanceConfigService hrKpiPostPerformanceConfigService;

    @Resource
    private HrKpiUserPerformanceHeaderMapper hrKpiUserPerformanceHeaderMapper;

    @Autowired
    private Executor asyncTaskExecutor;

    @Autowired
    private PushMsgService pushMsgService;



    /**
     * 启动考核
     *
     * @param hrKpiUserPerformanceHeaderForm
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveHeader(HrKpiUserPerformanceHeaderForm hrKpiUserPerformanceHeaderForm) {
        // // 构建满足未被删除的查询条件 （del_flag 0:存在 1：删除）
        // LambdaQueryWrapper<HrKpiPostPerformanceConfig> lambdaQueryWrapper = new LambdaQueryWrapper<HrKpiPostPerformanceConfig>()
        //         .eq(HrKpiPostPerformanceConfig::getDelFlag, 0);      //根据是否存在(del_flag)来查询配置信息
        // List<HrKpiPostPerformanceConfig> hrKpiPostPerformanceConfigs = hrKpiPostPerformanceConfigService.list(lambdaQueryWrapper);
        // List<Long> postIds = new ArrayList<>();       //获取岗位ids
        // for (HrKpiPostPerformanceConfig hrKpiPostPerformanceConfig : hrKpiPostPerformanceConfigs) {
        //     postIds.add(hrKpiPostPerformanceConfig.getPostId());
        // }
        //
        // LambdaQueryWrapper<HrKpiUserAssessorConfig> hrKpiUserAssessorConfigLambdaQueryWrapper = new LambdaQueryWrapper<HrKpiUserAssessorConfig>()
        //         .eq(HrKpiUserAssessorConfig::getDelFlag, 0)          //根据是否存在(del_flag)来查询配置信息
        //         .eq(HrKpiUserAssessorConfig::getPerformancType, hrKpiUserPerformanceHeaderForm.getPerformanceType())
        //         .in(HrKpiUserAssessorConfig::getPostId, postIds);

        // 获取满足参加条件的员工id(入职时间早于考核启动月的15号)
        // 获取考核周期上个月15号的时间对象
        LocalDate suitableTime = getSuitableTime(hrKpiUserPerformanceHeaderForm.getPerformancePeriod());
        // 获取满足考核时间的员工id集合(id对应岗位必须存在考核指标)
        List<Long> suitableUserIds = hrKpiUserPerformanceDetailMapper.getSuitableUserIds(suitableTime);

        LambdaQueryWrapper<HrKpiUserAssessorConfig> hrKpiUserAssessorConfigLambdaQueryWrapper = new LambdaQueryWrapper<HrKpiUserAssessorConfig>()
                .eq(HrKpiUserAssessorConfig::getDelFlag, 0)          //根据是否存在(del_flag)来查询配置信息
                .eq(HrKpiUserAssessorConfig::getPerformanceType, hrKpiUserPerformanceHeaderForm.getPerformanceType())
                .in(HrKpiUserAssessorConfig::getUserId, suitableUserIds);

        //通过考核类型查询hr_kpi_user_assessor_config所对应的信息
        List<HrKpiUserAssessorConfig> hrKpiUserAssessorConfigList = hrKpiUserAssessorConfigService.list(hrKpiUserAssessorConfigLambdaQueryWrapper);
        //给Header表赋值
        List<HrKpiUserPerformanceHeader> hrKpiUserPerformanceHeaderList = new ArrayList<>();
        List<Long> postIds2 = new ArrayList<>();        //获取岗位id集合
        HrKpiUserPerformanceHeader hrKpiUserPerformanceHeader;
        for (HrKpiUserAssessorConfig hrKpiUserAssessorConfig : hrKpiUserAssessorConfigList) {
            hrKpiUserAssessorConfig.setId(null);
            postIds2.add(hrKpiUserAssessorConfig.getPostId());
            //将hrKpiUserAssessorConfig转换为hrKpiUserPerformanceHeader对象赋值给hrKpiUserPerformanceHeader对象
            hrKpiUserPerformanceHeader = ConvertUtil.sourceToTarget(hrKpiUserAssessorConfig, HrKpiUserPerformanceHeader.class);
            hrKpiUserPerformanceHeader.setPerformanceType(hrKpiUserPerformanceHeaderForm.getPerformanceType());
            hrKpiUserPerformanceHeader.setStatus(hrKpiUserPerformanceHeaderForm.getStatus());
            hrKpiUserPerformanceHeader.setStartDate(hrKpiUserPerformanceHeaderForm.getStartDate());
            hrKpiUserPerformanceHeader.setEndWriteDate(hrKpiUserPerformanceHeaderForm.getEndWriteDate());
            hrKpiUserPerformanceHeader.setEndAssessorDate(hrKpiUserPerformanceHeaderForm.getEndAssessorDate());
            hrKpiUserPerformanceHeader.setPerformancePeriod(hrKpiUserPerformanceHeaderForm.getPerformancePeriod());
            hrKpiUserPerformanceHeader.setStartDate(LocalDate.now());
            hrKpiUserPerformanceHeaderList.add(hrKpiUserPerformanceHeader);
        }
        hrKpiUserPerformanceHeaderService.saveBatch(hrKpiUserPerformanceHeaderList);        //新增Header表
        //新增指标占比评分详情
        hrKpiUserPerformanceDetailService.saveInfos(hrKpiUserAssessorConfigList, postIds2);

        //单独开一个线程去发送企业微信
        // CompletableFuture.runAsync(() -> {
        //     pushMsgService.pushWriteMsgToEmployee(hrKpiUserPerformanceHeaderList);
        // }, asyncTaskExecutor);


    }

    /**
     * 获取开启考核周期的上个月的15号时间进行返回 格式:yyyy-MM-dd
     * @param performancePeriod
     * @return
     */
    private LocalDate getSuitableTime(String performancePeriod) {
        String[] performancePeriodSplit = performancePeriod.split("-");
        String resultYear = performancePeriodSplit[0];
        String resultMonth = performancePeriodSplit[1];
        Integer monthInt = new Integer(resultMonth);
        monthInt = monthInt - 1;
        // 如果为当年1月份的处理(月份为12，年数-1)
        if (monthInt == 0){
            monthInt = 12;
            Integer yearInt = new Integer(resultYear);
            yearInt -= 1;
            resultYear = yearInt.toString();
        }
        resultMonth = monthInt.toString();
        if (resultMonth.toCharArray().length <= 1) {
            resultMonth = 0 + resultMonth;
        }
        LocalDate resultDate = null;
        String resultTime = resultYear + "-" + resultMonth + "-" + 15;
        resultDate = LocalDate.parse(resultTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return resultDate;
    }

    /**
     * 保存员工填写和评分人评分信息
     *
     * @param headerUpdate
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveWriteInfo(HrKpiUserPerformanceHeaderUpdateForm headerUpdate) {
        //先修改head信息
        HrKpiUserPerformanceHeader head =
                ConvertUtil.sourceToTarget(headerUpdate, HrKpiUserPerformanceHeader.class);
        hrKpiUserPerformanceHeaderService.updateById(head);


        //修改员工填写信息
        List<HrKpiUserPerformanceDetailUserUpdateForm> userSelfMarkDetailFormList = headerUpdate.getUserSelfMarkDetailFormList();
        if (ComUtil.isNotNullList(userSelfMarkDetailFormList)) {
            boolean flag = checkUserDate(headerUpdate.getId());
            List<HrKpiUserPerformanceDetail> hrKpiUserPerformanceDetailList = ConvertUtil.sourceToTargets(userSelfMarkDetailFormList, HrKpiUserPerformanceDetail.class);
            if (flag) {
                hrKpiUserPerformanceDetailService.updateBatchById(hrKpiUserPerformanceDetailList);
            } else {
                return flag;
            }
        }


        //修改第一评分人
        List<HrKpiUserPerformanceDetailForm> accessOneDetailFormList = headerUpdate.getAccessOneDetailFormList();
        if (ComUtil.isNotNullList(accessOneDetailFormList)) {
            boolean flag = checkDate(headerUpdate.getId());
            List<HrKpiUserPerformanceDetail> hrKpiUserPerformanceDetailList = ConvertUtil.sourceToTargets(accessOneDetailFormList, HrKpiUserPerformanceDetail.class);
            if (flag) {
                hrKpiUserPerformanceDetailService.updateBatchById(hrKpiUserPerformanceDetailList);
            } else {
                return flag;
            }
        }

        //修改第二评分人
        List<HrKpiUserAssessor2DetailForm> accessTwoDetailFormList = headerUpdate.getAccessTwoDetailFormList();
        if (ComUtil.isNotNullList(accessTwoDetailFormList)) {
            boolean flag = checkDate(headerUpdate.getId());
            List<HrKpiUserPerformanceDetail> hrKpiUserPerformanceDetailList = ConvertUtil.sourceToTargets(accessTwoDetailFormList, HrKpiUserPerformanceDetail.class);
            if (flag) {
                hrKpiUserPerformanceDetailService.updateBatchById(hrKpiUserPerformanceDetailList);
            } else {
                return flag;
            }
        }
        return true;
    }

    /**
     * 提交员工填写和评分人评分信息
     *
     * @param headerUpdate
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitInfo(HrKpiUserPerformanceHeaderUpdateForm headerUpdate) {
        //先修改head信息
        HrKpiUserPerformanceHeader head =
                ConvertUtil.sourceToTarget(headerUpdate, HrKpiUserPerformanceHeader.class);

        //修改员工填写信息
        List<HrKpiUserPerformanceDetailUserUpdateForm> userSelfMarkDetailFormList = headerUpdate.getUserSelfMarkDetailFormList();
        if (ComUtil.isNotNullList(userSelfMarkDetailFormList)) {
            boolean flag = checkUserDate(headerUpdate.getId());
            List<HrKpiUserPerformanceDetail> hrKpiUserPerformanceDetailList = ConvertUtil.sourceToTargets(userSelfMarkDetailFormList, HrKpiUserPerformanceDetail.class);
            if (flag) {
                hrKpiUserPerformanceDetailService.updateBatchById(hrKpiUserPerformanceDetailList);
            } else {
                return flag;
            }
            head.setStatus(EMP_COMPLETE_STRINGS);
        }


        //修改第一评分人
        List<HrKpiUserPerformanceDetailForm> accessOneDetailFormList = headerUpdate.getAccessOneDetailFormList();
        if (ComUtil.isNotNullList(accessOneDetailFormList)) {
            boolean flag = checkDate(headerUpdate.getId());
            List<HrKpiUserPerformanceDetail> hrKpiUserPerformanceDetailList = ConvertUtil.sourceToTargets(accessOneDetailFormList, HrKpiUserPerformanceDetail.class);
            if (flag) {
                hrKpiUserPerformanceDetailService.updateBatchById(hrKpiUserPerformanceDetailList);
            } else {
                return flag;
            }
            head.setAssessor1Status(true);
        }

        //修改第二评分人
        List<HrKpiUserAssessor2DetailForm> accessTwoDetailFormList = headerUpdate.getAccessTwoDetailFormList();
        if (ComUtil.isNotNullList(accessTwoDetailFormList)) {
            boolean flag = checkDate(headerUpdate.getId());
            List<HrKpiUserPerformanceDetail> hrKpiUserPerformanceDetailList = ConvertUtil.sourceToTargets(accessTwoDetailFormList, HrKpiUserPerformanceDetail.class);
            if (flag) {
                hrKpiUserPerformanceDetailService.updateBatchById(hrKpiUserPerformanceDetailList);
            } else {
                return flag;
            }
            head.setAssessor2Status(true);
        }

        LambdaQueryWrapper<HrKpiUserPerformanceHeader> lambdaQueryWrapper =
                Wrappers.<HrKpiUserPerformanceHeader>lambdaQuery()
                        .eq(HrKpiUserPerformanceHeader::getId, head.getId())
                        .and(headtemp -> {
                            headtemp.eq(HrKpiUserPerformanceHeader::getAssessor1Status, Boolean.TRUE)
                                    .or()
                                    .eq(HrKpiUserPerformanceHeader::getAssessor2Status, Boolean.TRUE);
                        });

        long count = hrKpiUserPerformanceHeaderService.count(lambdaQueryWrapper);
        boolean pass = (head.getAssessor1Status() != null && head.getAssessor1Status())
                && (head.getAssessor2Status() != null && head.getAssessor2Status());

        if (count > 0 || pass) {
            head.setStatus(ASSESSOR_COMPLETE_STRINGS);

            //根据headid去获取head信息
            HrKpiUserPerformanceHeader header = hrKpiUserPerformanceHeaderService.getById(head.getId());
            sendMsgToEmp(header.getId(), header.getUserId());
        }
        hrKpiUserPerformanceHeaderService.updateById(head);
        return true;
    }

    /**
     * 判断员工是否在规定时间填报
     *
     * @param id
     */
    public boolean checkUserDate(Long id) {
        boolean flag = false;
        LambdaQueryWrapper<HrKpiUserPerformanceHeader> lambdaQueryWrapper = new LambdaQueryWrapper<HrKpiUserPerformanceHeader>()
                .eq(HrKpiUserPerformanceHeader::getId, id);
        HrKpiUserPerformanceHeader hrKpiUserPerformanceHeader = hrKpiUserPerformanceHeaderService.getOne(lambdaQueryWrapper);
        LocalDate dateNow = LocalDate.now();          //获取当前时间
        if (dateNow.isBefore(hrKpiUserPerformanceHeader.getEndWriteDate()) || dateNow.isEqual(hrKpiUserPerformanceHeader.getEndWriteDate())) {
            flag = true;
        }
        return flag;
    }

    /**
     * 判断评分人是否在规定时间评分
     *
     * @param id
     */
    public boolean checkDate(Long id) {
        boolean flag = false;
        LambdaQueryWrapper<HrKpiUserPerformanceHeader> lambdaQueryWrapper = new LambdaQueryWrapper<HrKpiUserPerformanceHeader>()
                .eq(HrKpiUserPerformanceHeader::getId, id);
        HrKpiUserPerformanceHeader hrKpiUserPerformanceHeader = hrKpiUserPerformanceHeaderService.getOne(lambdaQueryWrapper);
        LocalDate dateNow = LocalDate.now();          //获取当前时间
        if ((dateNow.isBefore(hrKpiUserPerformanceHeader.getEndAssessorDate()) || dateNow.isEqual(hrKpiUserPerformanceHeader.getEndAssessorDate()))) {
            flag = true;
        }
        return flag;
    }

    /**
     * 多开线程去发送评分完成信息
     *
     * @param taskId
     * @param userId
     */
    private void sendMsgToEmp(Long taskId, Long userId) {
        CompletableFuture.runAsync(() -> {
            pushMsgService.pushCompleteMsgToEmployee(taskId, userId);
        }, asyncTaskExecutor);
    }

    /**
     * 通过用户id查询header详情
     *
     * @param userId
     * @return
     */
    @Override
    public HrKpiUserPerformanceHeaderVO getHeaderInfo(Long userId) {
        LambdaQueryWrapper<HrKpiUserPerformanceHeader> lambdaQueryWrapper = new LambdaQueryWrapper<HrKpiUserPerformanceHeader>()
                .eq(HrKpiUserPerformanceHeader::getDelFlag, 0)
                .eq(HrKpiUserPerformanceHeader::getUserId, userId);
        HrKpiUserPerformanceHeader hrKpiUserPerformanceHeader = hrKpiUserPerformanceHeaderService.getOne(lambdaQueryWrapper);
        HrKpiUserPerformanceHeaderVO hrKpiUserPerformanceHeaderVO = ConvertUtil.sourceToTarget(hrKpiUserPerformanceHeader, HrKpiUserPerformanceHeaderVO.class);
        return hrKpiUserPerformanceHeaderVO;
    }

    /**
     * 员工考核列表
     *
     * @param hrKpiUserPerformanceHeaderRequest
     * @return
     */
    @Override
    public PageVO<HrKpiUserPerformanceHeaderVO> getHrKpiUserPerformanceHeaderList(HrKpiUserPerformanceHeaderRequest hrKpiUserPerformanceHeaderRequest) {
        IPage<HrKpiUserPerformanceHeaderVO> page = hrKpiUserPerformanceHeaderMapper.findHrKpiUserPermanceHeader(hrKpiUserPerformanceHeaderRequest.toPage(), hrKpiUserPerformanceHeaderRequest);
        if (ComUtil.isNullList(page.getRecords())) {
            page.setRecords(null);
        }
        return PageVO.convertPage(page);
    }

    @Override
    public List<KpiUserHeaderExport> getExportDataList(HrKpiUserPerformanceHeaderRequest hrKpiUserPerformanceHeaderRequest) {
        //查询
        List<HrKpiUserPerformanceHeaderExcelVO> hrKpiUserPerformanceHeaderExcelVOList =
                hrKpiUserPerformanceHeaderMapper.findHrKpiUserPermanceHeaderExport(hrKpiUserPerformanceHeaderRequest);
        if (ComUtil.isNullList(hrKpiUserPerformanceHeaderExcelVOList)) {
            return null;
        }
        return ConvertUtil.sourceToTargets(hrKpiUserPerformanceHeaderExcelVOList,KpiUserHeaderExport.class);
    }

    /**
     * 修改结束填报、评分时间
     *
     * @param hrKpiUserPerformanceHeaderTimeUpdateForm
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEndWriteAssessorTime(HrKpiUserPerformanceHeaderTimeUpdateForm hrKpiUserPerformanceHeaderTimeUpdateForm) throws Exception {
        hrKpiUserPerformanceHeaderTimeUpdateForm.setUpdateBy(UserIPUtil.getCurrentUserName());
        hrKpiUserPerformanceHeaderTimeUpdateForm.setUpdateTime(LocalDateTime.now());
        if (null != hrKpiUserPerformanceHeaderTimeUpdateForm.getId()) {
            if(hrKpiUserPerformanceHeaderMapper.updateEndWriteAssessorTimeById(hrKpiUserPerformanceHeaderTimeUpdateForm) < 0){
                throw new Exception("修改失败！");
            }
            return;
        }
        if (hrKpiUserPerformanceHeaderMapper.updateEndWriteAssessorTimeByUserId(hrKpiUserPerformanceHeaderTimeUpdateForm) < 0){
            throw new Exception("修改失败！");
        }
    }

    /**
     * 根据id查询详情
     *
     * @param id
     * @return
     */
    @Override
    public HrKpiUserPerformanceHeaderVO myGetById(Long id) {
        // LambdaQueryWrapper<HrKpiUserPerformanceHeader> lambdaQueryWrapper = new LambdaQueryWrapper<HrKpiUserPerformanceHeader>()
        //         .eq(HrKpiUserPerformanceHeader::getDelFlag, 0)
        //         .eq(HrKpiUserPerformanceHeader::getId, id);
        // HrKpiUserPerformanceHeader hrKpiUserPerformanceHeader = hrKpiUserPerformanceHeaderService.getOne(lambdaQueryWrapper);
        // HrKpiUserPerformanceHeaderVO hrKpiUserPerformanceHeaderVO = ConvertUtil.sourceToTarget(hrKpiUserPerformanceHeader, HrKpiUserPerformanceHeaderVO.class);
        HrKpiUserPerformanceHeaderVO hrKpiUserPerformanceHeaderVO = hrKpiUserPerformanceHeaderMapper.mySelectById(id);
        return hrKpiUserPerformanceHeaderVO;
    }
}
